package org.commons;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ByteFunctions {

	public static final byte[] ZEROASBYTES = intToByteArray(0), ONEASBYTES = intToByteArray(1), NEGONEASBYTES = intToByteArray(-1);
	
	private static final char[] HEX_CHARS = {'0', '1', '2', '3',
		'4', '5', '6', '7',
		'8', '9', 'a', 'b',
		'c', 'd', 'e', 'f',};

	public static String asHex (byte hash[]) {
		char buf[] = new char[hash.length * 2];
		for (int i = 0, x = 0; i < hash.length; i++) {
			buf[x++] = HEX_CHARS[(hash[i] >>> 4) & 0xf];
			buf[x++] = HEX_CHARS[hash[i] & 0xf];
		}
		return new String(buf);
	}

	/**
	 * La funzione intToByteArray() coverte un intero in un array di Byte
	 *
	 * @param value valore da convertire
	 * @return byte[]
	 */
	public static final byte[] intToByteArray(int value) {
		return new byte[] {
				(byte)(value >>> 24),
				(byte)(value >>> 16),
				(byte)(value >>> 8),
				(byte)value};
	}

	/**
	 * La funzione byteArrayToInt() coverte un array di Byte in un intero.
	 *
	 * @param b array di byte da convertire
	 * @return int
	 */
	public static int byteArrayToInt(byte[] b) {
		return byteArrayToInt(b, 0);
	}

	/**
	 * La funzione byteArrayToInt() converte un array di byte in un intero a partire da un dato offset
	 *
	 * @param b array di byte da convertire
	 * @param offset 
	 * @return int
	 */
	public static int byteArrayToInt(byte[] b, int offset) {
		int value = 0;
		for (int i = 0; i < 4; i++) {
			int shift = (4 - 1 - i) * 8;
			value += (b[i + offset] & 0x000000FF) << shift;
		}
		return value;
	}
	
	/**
	 * La funzione getBytes() restituisce un array di byte che rappresenta l'oggetto obj
	 * @param obj oggetto
	 * @exception IOException 
	 * @return byte[]
	 */

	public static byte[] getBytes(Object obj) {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(bos);
			oos.writeObject(obj);
			oos.flush();
		}
		catch (IOException e) {
			e.printStackTrace();
			System.exit(0);
		}
		finally {
			try {
				oos.close();
				bos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		byte[] data = bos.toByteArray();
		return data;
	}

	/**
	 * La funzione getObject() restituisce un oggetto rappresentante un dato un array di byte
	 * @param bytes array di byte
	 * @exception  IOException , ClassNotFoundException
	 * @return Object
	 */
	public static Object getObject(byte[] bytes) {
		Object toReturn = null;
		if(bytes != null) {
			ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
			ObjectInputStream ois = null;
			try {
				ois = new ObjectInputStream(bais);
				toReturn = ois.readObject();
			} catch (IOException e) {
				e.printStackTrace();
				System.exit(0);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
				System.exit(0);
			}
			finally {
				try {
					ois.close();
					bais.close();
				} catch (IOException e) {
					e.printStackTrace();
				}

			}
		}
		return toReturn;
	}
}
